import 'dart:async';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import '../public.dart';

class WebViewPage extends StatefulWidget {
  final String url;
  const WebViewPage({Key key, this.url}) : super(key: key);
  @override
  _WebViewPageState createState() => _WebViewPageState();
}

class _WebViewPageState extends State<WebViewPage> {
  final Completer<WebViewController> _controller =
      Completer<WebViewController>();
  String title = '';
  bool isLoading = true;
  ThemeProvider theme;
  @override
  Widget build(BuildContext context) {
    theme = Provider.of<ThemeProvider>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
        centerTitle: true,
        leadingWidth: 88,
        backgroundColor: theme.primaryColor,
        leading: NavigationControls(_controller.future),
        actions: <Widget>[
          MenuList(_controller.future),
        ],
      ),
      body: Stack(
        children: [
          WebView(
            initialUrl: widget.url,
            javascriptMode: JavascriptMode.unrestricted,
            // webview调用阅览器端javascript通道
            javascriptChannels: <JavascriptChannel>[
              _toasterJavascriptChannel(context),
            ].toSet(),
            onWebViewCreated: (WebViewController webViewController) {
              _controller.complete(webViewController);
            },
            onPageStarted: (String url) {},
            onPageFinished: (String url) {
              isLoading = false;
              _controller.future.then((webViewController) {
                webViewController.getTitle().then((res) {
                  title = res;
                  setState(() {});
                });
              });
              LogUtil.e('页面加载完成: $url $title');
            },
            gestureNavigationEnabled: true,
          ),
          LoadingComponent(
            show: isLoading,
            backgroundColor: theme.primaryColor,
            child: SizedBox.shrink(),
          )
        ],
      ),
    );
  }

  JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
    return JavascriptChannel(
        name: 'Toaster',
        onMessageReceived: (JavascriptMessage message) {
          ACGN.toast.dialog(context,
              content: Text(
                message.message,
                style: TextStyle(color: Colors.white),
              ),
              actions: [
                FlatButton(
                  color: Colors.transparent,
                  // radius: BorderRadius.circular(0),
                  child: Text(
                    '关闭',
                    style: TextStyle(color: Colors.white, fontSize: 16),
                  ),
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                ),
              ]);
        });
  }
}

enum MenuOptions {
  refresh,
  showUserAgent,
  clearCookies,
  clearCache,
}

class MenuList extends StatelessWidget {
  MenuList(this.controller);

  final Future<WebViewController> controller;
  final CookieManager cookieManager = CookieManager();

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<WebViewController>(
      future: controller,
      builder:
          (BuildContext context, AsyncSnapshot<WebViewController> snapshot) {
        return PopupMenuButton<MenuOptions>(
          onSelected: (MenuOptions value) {
            switch (value) {
              case MenuOptions.refresh:
                _onReresh(context, snapshot);
                break;
              case MenuOptions.showUserAgent:
                _onShowUserAgent(snapshot.data, context);
                break;
              case MenuOptions.clearCookies:
                _onClearCookies(context);
                break;
              case MenuOptions.clearCache:
                _onClearCache(snapshot.data, context);
                break;
            }
          },
          itemBuilder: (BuildContext context) => <PopupMenuItem<MenuOptions>>[
            PopupMenuItem<MenuOptions>(
              value: MenuOptions.refresh,
              child: Row(children: [
                NavigationControls._setIcon('refresh',
                    size: 16,
                    width: 16,
                    color: Colors.black26,
                    margin: EdgeInsets.only(right: 4)),
                Text('刷新')
              ]),
              enabled: snapshot.hasData,
            ),
            PopupMenuItem<MenuOptions>(
              value: MenuOptions.showUserAgent,
              child: Text('用户代理'),
              enabled: snapshot.hasData,
            ),
            PopupMenuItem<MenuOptions>(
              value: MenuOptions.clearCookies,
              child: Text('清除cookie'),
            ),
            PopupMenuItem<MenuOptions>(
              value: MenuOptions.clearCache,
              child: Text('清除缓存'),
            ),
          ],
        );
      },
    );
  }

  void _onReresh(
      BuildContext context, AsyncSnapshot<WebViewController> snapshot) async {
    final bool webViewReady = snapshot.connectionState == ConnectionState.done;
    if (webViewReady) {
      snapshot.data.reload();
    }
  }

  void _onShowUserAgent(
      WebViewController controller, BuildContext context) async {
    // 将用户代理字符串消息发送到我们注册的Toaster JavaScript使用webview通道
    await controller.evaluateJavascript(
        'Toaster.postMessage("User Agent: " + navigator.userAgent);');
  }

  void _onClearCache(WebViewController controller, BuildContext context) async {
    await controller.clearCache();
    ACGN.toast.message('清除缓存成功');
  }

  void _onClearCookies(BuildContext context) async {
    final bool hadCookies = await cookieManager.clearCookies();
    String message = '清除cookies成功';
    if (!hadCookies) {
      message = '没有需要清除的cookies';
    }
    ACGN.toast.message(message);
  }
}

class NavigationControls extends StatelessWidget {
  const NavigationControls(this.controller) : assert(controller != null);
  final Future<WebViewController> controller;

  static Widget _setIcon(String name,
      {double size, Color color, double width, EdgeInsets margin}) {
    return Container(
        width: width ?? 44,
        margin: margin ?? EdgeInsets.all(0),
        child: SVG.icon(name,
            size: size ?? 20,
            color: color ?? ColorUtil.rgba(255, 255, 255, 0.5)));
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<WebViewController>(
      future: controller,
      builder:
          (BuildContext context, AsyncSnapshot<WebViewController> snapshot) {
        final bool webViewReady =
            snapshot.connectionState == ConnectionState.done;
        final WebViewController _controller = snapshot.data;
        return Row(children: [
          GestureDetector(
            onTap: !webViewReady
                ? null
                : () async {
                    if (await _controller.canGoBack()) {
                      await _controller.goBack();
                    } else {
                      Navigator.pop(context);
                    }
                  },
            child: _setIcon('arrow_left'),
          ),
          GestureDetector(
              onTap: !webViewReady
                  ? null
                  : () async {
                      if (await _controller.canGoForward()) {
                        await _controller.goForward();
                      } else {
                        ACGN.toast.message('不能向前了。');
                      }
                    },
              child: _setIcon('arrow_right')),
        ]);
      },
    );
  }
}
